/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ru.niir.goodfil.ui;

import org.apache.log4j.Logger;
import ru.niir.goodfil.db.*;
import ru.niir.goodfil.db.audit.helpers.AuditHelper;
import ru.niir.goodfil.exceptions.CreateFailureException;
import ru.niir.goodfil.exceptions.RemoveFailureException;
import ru.niir.goodfil.exceptions.SettingNotFoundException;
import ru.niir.goodfil.exceptions.ValidationException;
import ru.niir.goodfil.ui.audit.JsfAuditHelper;
import ru.niir.goodfil.ui.utils.FacesUtils;
import ru.niir.goodfil.utils.validation.CreateCheckResult;
import ru.niir.goodfil.utils.validation.ValidationError;
import ru.niir.goodfil.utils.validation.ValidationResult;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import static ru.niir.goodfil.ui.Utils.setReservationDate;

/**
 * Бин авторизации клиентов.
 *
 * @author Носов А.В.
 * @author ksazonov
 */
public class ClientAuthorizationBean extends PageBean {


    private static final Logger logger = Logger.getLogger(ClientAuthorizationBean.class);

    /**
     * Имя пользователя
     */
    private String login;

    /**
     * Пароль пользователя
     */
    private String password;

    /**
     * Возвращает имя пользователя.
     *
     * @return имя пользователя
     */
    public String getLogin() {
        return login;
    }

    /**
     * Устанавливает имя пользователя.
     *
     * @param login имя пользователя
     */
    public void setLogin(String login) {
        this.login = login.trim();
    }

    /**
     * Возвращает пароль.
     *
     * @return пароль
     */
    public String getPassword() {
        return password;
    }

    /**
     * Устанавливаетя пароль.
     *
     * @param password пароль
     */
    public void setPassword(String password) {
        this.password = password.trim();
    }

    /**
     * Вход зарегистрированного клиента.
     */
    public void authorizationClient() throws IOException, ParseException {

        AuditHelper auditHelper = new JsfAuditHelper();
        HttpServletResponse response = (HttpServletResponse) getFacesContext().getExternalContext().getResponse();
        boolean isClient = false;

        if (login.equals("")) {
            facesError("Поле Имя пользователя обязательно для заполнения");
        }
        if (password.equals("")) {
            facesError("Поле Пароль обязательно для заполнения");
        }
        if (!gf().login(login, password)) {
            facesError("Имя пользователя или пароль неверны");
            login = "";
            password = "";
            return;
        }

        //  Протоколируем попытку войти в систему
//        getAuditService().logLoginAttempt(auditHelper.getIp(), login);


        User u = gf().getUserByLogin(login);
        login = "";
        password = "";

        if (u.getClientId() != null) {
            Client c = gf().getClientById(u.getClientId());
//            ClientGroup cg = gf().getClientGroupById(c.getClientGroupId());
            if (c.getManagerId() == null) {
                facesError("Вход в систему не возможен");
            }
            if (!c.isActive()) {
                facesError("Ваша учетная запись не активна");
            }
//            if (!cg.isActive()) facesError("Ваша клиентская группа не активна");
            if (hasFacesErrors()) {
                login = "";
                password = "";
                return;
            }

            // Убиваем пустые заказы.
            List<Order> orders = gf().getOrdersByClientId(u.getId());
            for (Order order : orders) {
                List<OrderItem> orderItems = gf().getOrderItemsByOrderId(order.getId());
                if (orderItems.size() < 1) {
                    try {
                        gf().removeOrder(order.getId());
                    } catch (RemoveFailureException ex) {
                        logger.error(ex);
                        ex.printStackTrace();
                        String[] objs = ex.getRemoveCheckResult().getLinkedObjects();
                        for (String obj : objs) {
                            facesError("Заказ нельзя удалить, т.к. он связан с другими объектами.");
                            break;
                        }
                    }
                }
            }

            List<OrderItem> orderItems = getSessionBean().getOrderItems(); // Вытаскиваем список товара до авторизации
            getSessionBean().setSelectedClientId(u.getClientId()); // Устанавливаем идентификаторклиента
            try {
                getSessionBean().setOrderItems(orderItems); // Складываем 2 списка.
            } catch (RemoveFailureException ex) {
                logger.error(ex);
                ex.printStackTrace();
                String[] objs = ex.getRemoveCheckResult().getLinkedObjects();
                for (String obj : objs) {
                    facesError("Товар нельзя удалить, т.к. он связан с другими объектами.");
                    break;
                }
            } catch (CreateFailureException ex) {
                logger.error(ex);
                ex.printStackTrace();
                CreateCheckResult createCheckResult = ex.getResult();
                facesError(createCheckResult.getMsg());
            } catch (ValidationException ex) {
                logger.error(ex);
                ex.printStackTrace();
                ValidationResult validationResult = ex.getResult();
                for (ValidationError error : validationResult.getErrors()) {
                    facesError(error.toHumanString());
                }
            } catch (SettingNotFoundException ex) {
                logger.error(ex);
                ex.printStackTrace();
                facesError(ex.getSettingName());
            }
            getSessionBean().getOrderItems(); // Ну вообще голова не варит. Передернули список.

            //  Зарегистрировать вход клиента
            getSecurityBean().loginClient(u.getClientId(), u.getId());

            //  Протоколируем вход клиента
            getAuditService().logLoginSuccess(auditHelper.getIp(), u.getLogin());

            //  Инициализируем клиентский бин
            ClientGoodsSearchBean clientGoodsSearchBean = FacesUtils.getManagedBean("ClientGoodsSearchBean");
            clientGoodsSearchBean.init(u.getClientId());

            response.sendRedirect("ClientGoodsPage.jsf");
        } else {
            //  Зарегистрировать вход сотрудника в систему
            getSecurityBean().loginEmployee(u.getId());

            //  Протоколируем вход клиента
//            getAuditService().logLoginSuccess(auditHelper.getIp(), u.getLogin());

            if(u.getUserRoleId() == Role.KASSA){
                response.sendRedirect("razvoz");
            }

           else if (u.getUserRoleId() == 3) {
                //  Кладовщик
                response.sendRedirect("sk1");
            } else {
                //  НЕ Кладовщик
                if (Logs1CBean.get1CIsRunning(gf())) {
                    response.sendRedirect("start");
                } else {
                    response.sendRedirect("c1.html");
                }
            }
        }
    }

    /**
     * Выход клиента из авторизации.
     */
    public void exitClient() {

        getSecurityBean().logout();

        Order order = new Order();
        setReservationDate(order, gf());

        getSessionBean().setOrder(order);
        try {
            getSessionBean().setOrderItems(new ArrayList<OrderItem>());
        } catch (RemoveFailureException ex) {
            logger.error(ex);
            ex.printStackTrace();
            String[] objs = ex.getRemoveCheckResult().getLinkedObjects();
            for (String obj : objs) {
                facesError("Товар нельзя удалить, т.к. он связан с другими объектами.");
                break;
            }
        } catch (CreateFailureException ex) {
            logger.error(ex);
            ex.printStackTrace();
            CreateCheckResult createCheckResult = ex.getResult();
            facesError(createCheckResult.getMsg());
        } catch (ValidationException ex) {
            logger.error(ex);
            ex.printStackTrace();
            ValidationResult validationResult = ex.getResult();
            for (ValidationError error : validationResult.getErrors()) {
                facesError(error.toHumanString());
            }
        } catch (SettingNotFoundException ex) {
            logger.error(ex);
            ex.printStackTrace();
            facesError(ex.getSettingName());
        }
    }
}
